<?php

/* 
 * Author: Mario Jose
 * email: mariognu-free@yahoo.com.br
 *
 * created: Januery, 5th 2010
 * modified: -
*/

/*
  This script is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This script is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * Create parser to PubMed article xml file with Title, PDBID, PubDate
 * and Author
*/

class rXMLPubmed
   {
   /*
    * vars with content file and errors control
    *
    * @var resource $xmlParser Handle to parser
    * 
    * @var array $element Has the current element in an parental elements tree
    * @var array $tree Has the tree with the specific elements
    *
    * @var intiger $indexElement Has the index to the $element
    * @var intiger $indexTree Has the index to the $tree
    * @var intiger $indexAuthor Has the index to the $element[AuthorList]
   */   
   var $xmlParser;
   
   var $element;
   var $tree;
   
   var $indexElement = 0;
   var $indexTree = 0;
   var $indexAuthor = 0;

   /*
    * Define parser parameters
   */   
   function rXMLPubmed()
      {
      $this->xmlParser = xml_parser_create();
      
      // to reference callback in the class
      xml_set_object ($this->xmlParser, $this);
      
      // Enable case sensitive to element name and encoding
      xml_parser_set_option($this->xmlParser, XML_OPTION_CASE_FOLDING, false);
      xml_parser_set_option($this->xmlParser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
      
      xml_set_element_handler($this->xmlParser, "startTag", "endTag");
      xml_set_character_data_handler($this->xmlParser, "dataTag");
      } // end function

   /*
    * Open the xml file and run the parser
    *
    * @param string $fileName Has the file name to be read
   */    
   function parseXML($fileName)
      {      
      if (!$fileHandle = fopen($fileName, "r")) die("Could not open data");
      
      // Parse data from file read
      $readedData = fread($fileHandle, filesize($fileName));
      xml_parse($this->xmlParser, $readedData, feof($fileHandle));

      xml_parser_free($this->xmlParser); // free parser from memory
      } // end function

   /*
    * Executed when an open element is found
    *
    * @param resource $parser Handle reference to parser
    * @param string $name Name of current element
    * @param array $attrs Element's attribute 
   */   
   function startTag($parser, $name, $attrs)
      {
      if (isset($this->element[$this->indexElement])) $this->indexElement++;
      
      $this->element[$this->indexElement] = $name;
      
      if ($name == "PubmedArticle") {
         if (isset($this->tree[$this->indexTree])) {
            $this->indexTree++;
            $this->indexAuthor = 0;
         }
         $this->tree[$this->indexTree] = array();         
      }
      
      if ($name == "PMID" && $this->element[($this->indexElement - 1)] == "MedlineCitation")
         $this->tree[$this->indexTree]["PMID"] = "";
      
      if ($name == "PubDate" && $this->element[($this->indexElement - 1)] == "JournalIssue")
         $this->tree[$this->indexTree]["PubDate"] = "";


      if ($name == "ArticleTitle") 
         $this->tree[$this->indexTree]["ArticleTitle"] = "";
      
      if ($name == "Author" && $this->element[($this->indexElement - 1)] == "AuthorList"
         && $this->element[($this->indexElement - 2)] == "Article")
         {
         if (!isset($this->tree[$this->indexTree]["AuthorList"]))
            $this->tree[$this->indexTree]["AuthorList"] = array();
         
         if (isset($this->tree[$this->indexTree]["AuthorList"][$this->indexAuthor]))
            $this->indexAuthor++;
            
         $this->tree[$this->indexTree]["AuthorList"][$this->indexAuthor] = "";
         }

      } // end function

   /*
    * Executed when an close element is found
    *
    * @param resource $parser Handle reference to parser
    * @param string $name Name of current element
   */   
   function endTag($parser, $name)
      {
      $this->element[$this->indexElement] = "";
      $this->indexElement--;
      } // end function

   /*
    * Executed when data elements is found
    *
    * @param resource $parser Handle reference to parser
    * @param string $name Name of current element
   */   
   function dataTag($parser, $data)
      {
      if ($this->element[($this->indexElement)] == "PMID" && $this->element[($this->indexElement - 1)] == "MedlineCitation")
         $this->tree[$this->indexTree]["PMID"] = htmlentities($data);

      if (($this->element[$this->indexElement] == "Year" || $this->element[$this->indexElement] == "Month"
          || $this->element[$this->indexElement] == "Day") && ($this->element[($this->indexElement - 1)] == "PubDate"
          && $this->element[($this->indexElement - 2)] == "JournalIssue"))
         $this->tree[$this->indexTree]["PubDate"] .= htmlentities($data) . " ";
      
      if ($this->element[($this->indexElement)] == "ArticleTitle") 
         $this->tree[$this->indexTree]["ArticleTitle"] = htmlentities($data);

      if (($this->element[($this->indexElement)] == "LastName" || $this->element[($this->indexElement)] == "Initials")
          && ($this->element[($this->indexElement - 1)] == "Author" && $this->element[($this->indexElement - 2)] == "AuthorList"))
         {
         if ($this->element[($this->indexElement)] == "LastName")
            $this->tree[$this->indexTree]["AuthorList"][$this->indexAuthor] .= htmlentities($data);
         
         if ($this->element[($this->indexElement)] == "Initials")
            $this->tree[$this->indexTree]["AuthorList"][$this->indexAuthor] .= ", " . htmlentities($data);
         }
     
      } // end function
   
   } // end class rXML

?>